#include "netlink.h"

#include <errno.h>
#include <netlink/genl/ctrl.h>
#include <netlink/genl/genl.h>
#include <netlink/handlers.h>
#include <netlink/netlink.h>
#include <netlink/socket.h>

#include "log.h"

int finish_handler(struct nl_msg *msg, void *arg) {
  int *ret = arg;
  *ret = 0;
  return NL_OK;
}

int initNl80211(Netlink* nl, Wifi* w, nl_callback *callback) {
  nl->socket = nl_socket_alloc();
  if (!nl->socket) {
    log_err("NETLINK", "Failed to allocate netlink socket.\n");
    return -ENOMEM;
  }

  nl_socket_set_buffer_size(nl->socket, 0, 0);

  if (genl_connect(nl->socket)) {
    log_err("NETLINK", "Failed to connect to netlink socket.\n");
    nl_close(nl->socket);
    nl_socket_free(nl->socket);
    return -ENOLINK;
  }

  nl->id = genl_ctrl_resolve(nl->socket, "nl80211");
  if (nl->id< 0) {
    log_err("NETLINK", "Nl80211 interface not found.\n");
    nl_close(nl->socket);
    nl_socket_free(nl->socket);
    return -ENOENT;
  }

  if (callback != NULL) {
      nl->cb1 = nl_cb_alloc(NL_CB_DEFAULT);
      if (!nl->cb1) {
         log_err("NETLINK", "Failed to allocate netlink callback.\n");
         nl_close(nl->socket);
         nl_socket_free(nl->socket);
         return ENOMEM;
      }

      nl_cb_set(nl->cb1, NL_CB_VALID , NL_CB_CUSTOM, callback, w);
      nl_cb_set(nl->cb1, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &(nl->result));
  }

  return nl->id;
}
